package org.lee.util;

import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.BreakClear;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

/**
 * @author jackielee
 * @version 1.0
 * @description Pdf2Doc
 * @date 2021/6/2
 */
public class Pdf2Doc {
  public static void pdf2Word(String pdfFile, String outPath) {
    File pdf = new File(pdfFile);
    String tempDir = "./temp";
    try (PDDocument doc = Loader.loadPDF(pdf)) {
      int pageCount = doc.getNumberOfPages();
      String wordFileName =
          String.format("%s%s%s.docx", outPath, File.separator, FileUtils.getFileName(pdf));
      XWPFDocument document = new XWPFDocument();
      FileOutputStream out = new FileOutputStream(wordFileName);
      String tmpImage = String.format("%s%simages", tempDir, File.separator);
      FileUtils.checkDir(tmpImage);
      for (int i = 0; i < pageCount; ++i) {
        PDPage page = doc.getPage(i);
        PDResources resources = page.getResources();

        Iterator<COSName> iterator = resources.getXObjectNames().iterator();
        while (iterator.hasNext()) {
          COSName cosName = iterator.next();

          if (resources.isImageXObject(cosName)) {
            PDImageXObject imgXObj = (PDImageXObject) resources.getXObject(cosName);
            File imgFile =
                new File(
                    String.format(
                        "%s%s%d.jpg", tmpImage, File.separator, System.currentTimeMillis()));
            FileOutputStream imgOut = new FileOutputStream(imgFile);

            BufferedImage oxImg = imgXObj.getImage();
            int width = oxImg.getWidth();
            int height = oxImg.getHeight();
            if (width > 600) {
              double ratio = 600.0 / (double) width;
              System.out.println("ratio:" + ratio);
              width = (int) (width * ratio);
              height = (int) (height * ratio);
              //              Thumbnails.of(oxImg)  // 保持高清，让可缩放
              //                  .scale(ratio)
              //                  .rotate(0)
              //                  .outputFormat("JPEG")
              //                  .toOutputStream(imgOut);
            }
            ImageIO.write(oxImg, "jpg", imgOut);

            imgOut.close();
            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun picRun = paragraph.createRun();
            FileInputStream imgIn = new FileInputStream(imgFile);
            picRun.addPicture(
                imgIn,
                XWPFDocument.PICTURE_TYPE_JPEG,
                imgFile.getPath(),
                Units.pixelToEMU(width),
                Units.pixelToEMU(height));
            imgIn.close();
          }
        }
        PDFTextStripper stripper = new PDFTextStripper();
        stripper.setSortByPosition(true);
        stripper.setStartPage(i);
        stripper.setEndPage(i);
        String text = stripper.getText(doc);

        XWPFParagraph textParagraph = document.createParagraph();
        String[] lines = text.split("[\r\n|\n]");
        for (String line : lines) {
          XWPFRun textRun = textParagraph.createRun();
          textRun.setText(line);
          textRun.setFontFamily("仿宋");
          textRun.setFontSize(11);
          textRun.addBreak(BreakClear.NONE);
        }
        textParagraph.setWordWrapped(true); // 自动换行
      }
      document.write(out);
      out.close();
      doc.close();
      System.out.println("end.");
    } catch (IOException | InvalidFormatException e) {
      e.printStackTrace();
    } finally {
      FileUtils.clearDir(tempDir);
    }
  }
}
